
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/signal.h>

#include <errno.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>

#define BUFFER_SIZE 1024

static void recvfrom_alarm(int sig) {

    return;
}

void dg_cli(FILE * fp, int sock_fd, const struct sockaddr * pservaddr, socklen_t servlen) {

    int     n = 0;
    const int on = 1;

    char send_line[BUFFER_SIZE], recv_line[BUFFER_SIZE + 1];
    socklen_t len;
    struct sockaddr * preply_addr;
    preply_addr = malloc(servlen);

    setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
    
    signal(SIGTERM, recvfrom_alarm);
    while (fgets(send_line, BUFFER_SIZE, fp) != NULL) {

        sendto(sock_fd, send_line, strlen(send_line), 0, pservaddr, servlen);

        alarm(5);
        for (; ; ) {

            len = servlen;
            n = recvfrom(sock_fd, recv_line, BUFFER_SIZE, 0, pservaddr, &len);
            if (n < 0) {

                if (errno == EINTR) {

                    break;
                }
                else {

                    printf("recvfrom error");
                    break;
                }
            }
            else {

                recv_line[n] = 0;
                printf("%s\n", recv_line);
            }
        }
    }
    free(preply_addr);
    close(sock_fd);
}

int main(int argc, char * argv[]) {


    int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);

    if (sock_fd < 0) {

        printf("create socket fd failure.\n");
        return EXIT_FAILURE;
    }
    struct sockaddr_in sa;
    bzero(&sa, sizeof(sa));

    sa.sin_family = AF_INET;
    sa.sin_port   = htons(13); 
    inet_pton(AF_INET, argv[1], &sa.sin_addr);

    dg_cli(stdin, sock_fd, (struct sockaddr*)&sa, sizeof(sa));
    return EXIT_SUCCESS;
}
// gcc -Wall -Wunused dgclicast1.c -o dgclicast1